﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using BCDto.Chats.Thread;
using BCService.Chats;

namespace BCTMSRESTful.Controllers.Chats
{
    [ApiExplorerSettings(GroupName = "Chats")]
    [Route("api/v1/Chats/[controller]")]
    public class ThreadsController : ChatBaseController
    {
        private readonly IThreadService threadService;

        public ThreadsController(IThreadService threadService)
        {
            this.threadService = threadService;
        }

        /// <summary>
        /// 获取会话列表。
        /// </summary>  
        /// <response code="200">一组会话列表。</response>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(IEnumerable<ThreadDto>), 200)]
        public IActionResult GetThreads()
        {
            var list = threadService.GetThreads();

            return this.Ok(list);
        }

        /// <summary>
        /// 获取指定的会话。
        /// </summary>
        /// <param name="threadId">会话编号。</param>
        /// <response code="200">指定的会话信息。</response>
        /// <response code="204">指定的会话不存在或已被删除。</response>
        /// <returns></returns>
        [HttpGet("{thread_id}")]
        [ProducesResponseType(typeof(ThreadDto), 200)]
        public IActionResult GetThread([FromRoute(Name = "thread_id")] long threadId)
        {
            var thread = threadService.GetThread(threadId);

            return this.Ok(thread);
        }

        /// <summary>
        /// 创建新会话。
        /// </summary>
        /// <param name="requestDto"></param>
        /// <response code="200">已存在的会话。</response>
        /// <response code="201">新会话已创建。</response>
        /// <returns></returns>
        /// <remarks>私人会话、客服会话在参数相同的情况下，可能并不会重复创建新会话，当有新会话创建时返回 201 的 HTTP 状态码，否则返回 200 的 HTTP 状态码。</remarks>
        [HttpPost]
        [ProducesResponseType(typeof(ThreadDto), 200)]
        [ProducesResponseType(typeof(ThreadDto), 201)]
        public IActionResult Create([FromBody] ThreadRequestDto requestDto)
        {
            var thread = threadService.Create(requestDto, out var threadIsNew);

            if (threadIsNew)
            {
                return this.Created(Url.Action(nameof(GetThread), new { thread_id = thread.ThreadId }), thread);
            }
            else
            {
                return this.Ok(thread);
            }
        }

        /// <summary>
        /// 修改指定的会话。
        /// </summary>
        /// <param name="threadId">会话编号。</param>
        /// <param name="requestDto"></param>
        /// <response code="200">指定的会话信息。</response>
        /// <response code="204">指定的会话不存在或已被删除。</response>
        /// <returns></returns>
        [HttpPost("{thread_id}")]
        [ProducesResponseType(typeof(ThreadDto), 200)]
        public IActionResult Update([FromRoute(Name = "thread_id")] long threadId, [FromBody] ThreadUpdateRequestDto requestDto)
        {
            var thread = threadService.Update(threadId, requestDto);

            return this.Ok(thread);
        }

        /// <summary>
        /// 关闭会话。
        /// </summary>
        /// <param name="threadId">会话编号。</param>
        /// <param name="requestDto"></param>
        /// <response code="200">指定的会话信息。</response>
        /// <response code="204">指定的会话不存在或已被删除。</response>
        /// <returns></returns>
        [HttpPost("{thread_id}/[action]")]
        [ProducesResponseType(typeof(ThreadDto), 200)]
        public IActionResult Close([FromRoute(Name = "thread_id")] long threadId, [FromBody] ThreadCloseRequestDto requestDto)
        {
            var thread = threadService.Close(threadId, requestDto);

            return this.Ok(thread);
        }

        /// <summary>
        /// 删除会话。
        /// </summary>
        /// <param name="threadId">会话编号。</param>
        /// <response code="204">指定的会话不存在或已被删除。</response>
        /// <returns></returns>
        [HttpDelete("{thread_id}")]
        public IActionResult Delete([FromRoute(Name = "thread_id")] long threadId)
        {
            threadService.Delete(threadId);

            return this.NoContent();
        }

        /// <summary>
        /// 将指定的会话/消息标记为已读。
        /// </summary>
        /// <param name="threadId">会话编号。</param>
        /// <param name="requestDto"></param>
        /// <response code="200">指定的会话信息。</response>
        /// <response code="204">指定的会话不存在或已被删除。</response>
        /// <returns></returns>
        [HttpPost("{thread_id}/[action]")]
        [ProducesResponseType(typeof(ThreadDto), 200)]
        public IActionResult MarkAsRead([FromRoute(Name = "thread_id")] long threadId, [FromBody] MarkAsReadRequestDto requestDto)
        {
            var thread = threadService.MarkAsRead(threadId, requestDto);

            return this.Ok(thread);
        }

        /// <summary>
        /// 添加会话参与人。
        /// </summary>
        /// <param name="threadId">会话编号。</param>
        /// <param name="requestDto"></param>
        /// <response code="200">指定的会话信息。</response>
        /// <response code="201">新会话已创建。</response>
        /// <response code="204">指定的会话不存在或已被删除。</response>
        /// <returns></returns>
        /// <remarks>如果指定的原会话为私人会话，则会创建新的群会话，同时返回 201 的 HTTP 状态码。</remarks>
        [HttpPost("{thread_id}/[action]")]
        [ProducesResponseType(typeof(ThreadDto), 200)]
        [ProducesResponseType(typeof(ThreadDto), 201)]
        public IActionResult AttachParticipants([FromRoute(Name = "thread_id")] long threadId, [FromBody] AttachParticipantsRequestDto requestDto)
        {
            var thread = threadService.AttachParticipants(threadId, requestDto);

            if (thread.ThreadId != threadId)
            {
                return this.Created(Url.Action(nameof(GetThread), new { thread_id = thread.ThreadId }), thread);
            }
            else
            {
                return this.Ok(thread);
            }
        }

        /// <summary>
        /// 移除会话参与人。
        /// </summary>
        /// <param name="threadId">会话编号。</param>
        /// <param name="requestDto"></param>
        /// <response code="200">指定的会话信息。</response>
        /// <response code="204">指定的会话不存在或已被删除。</response>
        /// <returns></returns>
        [HttpPost("{thread_id}/[action]")]
        [ProducesResponseType(typeof(ThreadDto), 200)]
        public IActionResult DetachParticipants([FromRoute(Name = "thread_id")] long threadId, [FromBody] DetachParticipantsRequestDto requestDto)
        {
            var thread = threadService.DetachParticipants(threadId, requestDto);

            return this.Ok(thread);
        }
    }
}
